package com.ls.common.aop.dal;

import com.ls.common.baseClass.mongodb.AbstractAuditingEntity;
import com.ls.base.utils.FieldUtil;
import com.ls.base.utils.StringUtil;
import com.ls.common.aop.core.IdGenerator;
import com.ls.common.aop.core.KeywordGenerator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.annotation.Id;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author: xiaosu
 * @date: 2018-09-20  21:37
 */

@Aspect
@Component
public class RepositorySaveMethodInterceptor {

    @Pointcut("execution(public * com.ls.modules.*.dal.mongodb..dao.*.save(..))")
    public void save() {
    }

    @Before("save()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容

        Object param = joinPoint.getArgs()[0];

        if (param instanceof Iterable) {
            ((Iterable) param).forEach(item -> onBeforeConvert(item));
        } else {
            onBeforeConvert(param);
        }

    }

    public void onBeforeConvert(Object source) {

        if (source != null && source instanceof IdGenerator) {
            ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {

                @Override
                public void doWith(Field field) throws IllegalArgumentException,
                        IllegalAccessException {
                    ReflectionUtils.makeAccessible(field);
                    if (field.isAnnotationPresent(Id.class) && field.get(source) == null) {
                        //设置自增ID
                        Object id = ((IdGenerator) source).generator();
                        field.set(source, id);

                    }
                }
            });

        }

        if (source != null && source instanceof KeywordGenerator) {
            ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {

                @Override
                public void doWith(Field field) throws IllegalArgumentException,
                        IllegalAccessException {

                    if (field.getName().equals("keyword") && FieldUtil.readField(source, field.getName()) == null) {
                        FieldUtil.writeField(source, field.getName(),
                                ((KeywordGenerator) source).keywordGenerator());
                    }
                }
            });

        }

        if (source != null && source instanceof AbstractAuditingEntity) {

            AbstractAuditingEntity entity = (AbstractAuditingEntity) source;

            String userId =null;

            if (entity.getCreateTime() == null) {
                entity.setCreateTime(new Date());
            }

            if (StringUtil.isBlank(entity.getCreatedBy())) {
                entity.setCreatedBy(userId == null ? "system" : userId);
            }

            entity.setLastModifiedBy(userId == null ? "system" : userId);
            entity.setUpdateTime(new Date());

        }

    }


}
